package com.proback.controller;

import com.proback.constant.ResponseCode;
import com.proback.dto.*;
import com.proback.entity.User;
import com.proback.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.ZoneId;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;


/**
 * 用户控制器，负责处理用户的登录、注册和删除请求。
 */
@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private com.proback.utils.JwtUtil jwtUtil;

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    /**
     * 用户登录接口
     *
     * @param request 包含手机号（account）和密码
     * @return 登录成功后返回用户信息和JWT token
     * @throws Exception 如果用户不存在或密码错误
     */
    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest request) throws Exception {
        try {
            User user = userService.login(request.getAccount(), request.getPassword());

            logger.info("[/login] 调用 jwtUtil 生成Token");
            String token = jwtUtil.generateToken(user.getAccount());

            return ResponseEntity.ok(new UserResponse(
                    user.getId(),
                    user.getAccount(),
                    user.getUsername(),
                    token
            ));
        } catch (Exception e) {
            Map<String, Object> body = new LinkedHashMap<>();
            body.put("timestamp", System.currentTimeMillis());
            body.put("status", HttpStatus.UNAUTHORIZED.value());

            if (e.getMessage().contains("用户不存在")) {
                body.put("error", "Not Found");
                body.put("message", "用户不存在");
            } else if (e.getMessage().contains("密码错误")) {
                body.put("error", "Unauthorized");
                body.put("message", "密码错误");
            } else {
                body.put("error", "Internal Server Error");
                body.put("message", e.getMessage());
            }

            return ResponseEntity
                    .status(HttpStatus.UNAUTHORIZED)
                    .body(body);
        }
    }

    /**
     * 用户注册接口
     *
     * @param request 包含注册所需信息的请求体，如账号、用户名和密码
     * @return ResponseEntity<ApiResponse<UserResponse>> 返回包含用户信息和JWT令牌的成功响应，
     *         或者在发生异常时返回错误信息
     */
    @PostMapping("/register")
    public ResponseEntity<ApiResponse<UserResponse>> register(@RequestBody RegisterRequest request) {
        try {
            User user = userService.register(
                    request.getAccount(),
                    request.getUsername(),
                    request.getPassword()
            );

            logger.info("[/register] 调用 jwtUtil 生成Token");
            String token = jwtUtil.generateToken(user.getAccount());
            UserResponse userResponse = new UserResponse(
                    user.getId(),
                    user.getAccount(),
                    user.getUsername(),
                    token
            );

            return ResponseEntity.ok(ApiResponse.success("注册成功", userResponse));
        } catch (Exception e) {
            int errorCode = e.getMessage().contains("手机号") ?
                    ResponseCode.ACCOUNT_EXISTS :
                    ResponseCode.BAD_REQUEST;

            return ResponseEntity.badRequest()
                    .body(ApiResponse.error(errorCode, e.getMessage()));
        }
    }

    /**
     * 删除指定用户接口
     *
     * @param id 用户ID
     * @param request HTTP请求对象，用于提取Token进行权限验证
     * @return 删除成功时返回成功提示
     * @throws Exception 如果删除失败则抛出异常
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<?> deleteUser(
            @PathVariable Integer id,
            HttpServletRequest request) {

        // 验证 Token 和用户 ID
        ResponseEntity<?> validationResult = validateTokenAndUserId(id, request);
        if (validationResult != null) return validationResult;

        try {
            userService.deleteUserById(id);
            return ResponseEntity.ok(ApiResponse.success("用户已删除", null));
        } catch (Exception e) {
            logger.error("删除用户失败: {}", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(ApiResponse.error(ResponseCode.SERVER_ERROR, "删除用户失败"));
        }
    }

    /**
     * 获取用户详细信息接口
     *
     * @param id 用户ID
     * @param request HTTP请求对象，用于提取Token进行权限验证
     * @return 包含用户基本信息和注册时间戳的响应对象
     * @throws Exception 当用户不存在或查询失败时抛出异常
     */
    @GetMapping("/{id}")
    public ResponseEntity<?> getUserDetail(
            @PathVariable Integer id,
            HttpServletRequest request) {

        // 验证 Token 和用户 ID
        ResponseEntity<?> validationResult = validateTokenAndUserId(id, request);
        if (validationResult != null) return validationResult;

        try {
            User user = userService.getUserById(id);
            long timestamp = user.getAddTime()
                    .atZone(ZoneId.systemDefault())
                    .toInstant()
                    .toEpochMilli();

            return ResponseEntity.ok(new UserQueryResponse(
                    user.getId(),
                    user.getAccount(),
                    user.getUsername(),
                    timestamp
            ));
        } catch (Exception e) {
            logger.error("获取用户详情失败: {}", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(ApiResponse.error(ResponseCode.SERVER_ERROR, "获取用户详情失败"));
        }
    }

    /**
     * 更新用户信息并生成新的JWT令牌
     *
     * @param request 包含用户ID和新用户名的更新请求对象
     * @param servletRequest HTTP请求对象，用于提取Token进行权限验证
     * @return 返回包含更新后用户信息和新生成的JWT令牌的响应对象
     * @throws Exception 如果更新过程中发生异常
     */
    @PutMapping("/update")
    public ResponseEntity<?> updateUser(
            @RequestBody UserUpdateRequest request,
            HttpServletRequest servletRequest) {

        // 验证 Token 和用户 ID
        ResponseEntity<?> validationResult = validateTokenAndUserId(request.getId(), servletRequest);
        if (validationResult != null) return validationResult;

        try {
            User updatedUser = userService.updateUsername(request.getId(), request.getUsername());
            String newToken = jwtUtil.generateToken(updatedUser.getAccount());

            return ResponseEntity.ok(new UserResponse(
                    updatedUser.getId(),
                    updatedUser.getAccount(),
                    updatedUser.getUsername(),
                    newToken
            ));
        } catch (Exception e) {
            logger.error("更新用户失败: {}", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(ApiResponse.error(ResponseCode.SERVER_ERROR, "更新用户失败"));
        }
    }

    /**
     * 修改用户密码接口
     *
     * @param request 包含用户ID、旧密码和新密码的请求对象
     * @param servletRequest HTTP请求对象，用于提取Token进行权限验证
     * @return 修改成功时返回成功消息
     * @throws Exception 如果用户不存在、旧密码错误或更新失败则抛出异常
     */
    @PutMapping("/changePassword")
    public ResponseEntity<?> changePassword(
            @RequestBody ChangePasswordRequest request,
            HttpServletRequest servletRequest) {

        // 验证 Token 和用户 ID
        ResponseEntity<?> validationResult = validateTokenAndUserId(request.getUserId(), servletRequest);
        if (validationResult != null) return validationResult;

        try {
            userService.changePassword(request.getUserId(), request.getOldPassword(), request.getNewPassword());
            return ResponseEntity.ok(ApiResponse.success("密码修改成功", null));
        } catch (Exception e) {
            String errorMsg = e.getMessage();
            int errorCode = ResponseCode.BAD_REQUEST;

            if (errorMsg.contains("旧密码错误")) {
                errorCode = ResponseCode.UNAUTHORIZED;
            } else if (errorMsg.contains("用户不存在")) {
                errorCode = ResponseCode.NOT_FOUND;
            }

            return ResponseEntity.badRequest()
                    .body(ApiResponse.error(errorCode, errorMsg));
        }
    }

    /**
     * 验证Token状态
     *
     * @param request 包含Token的请求体
     * @return 验证结果
     */
    @PostMapping("/validate-token")
    public ResponseEntity<?> validateToken(@RequestBody TokenValidationRequest request) {
        String token = request.getToken();

        if (token == null || token.isEmpty()) {
            logger.warn("Token验证失败: 空Token");
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error(ResponseCode.BAD_REQUEST, "Token不能为空"));
        }

        try {
            boolean isValid = jwtUtil.validateToken(token);

            // 添加详细调试信息
            Map<String, Object> response = new LinkedHashMap<>();
            response.put("valid", isValid);

            if (!isValid) {
                Date expiration = jwtUtil.getExpirationFromToken(token);
                response.put("expired_at", expiration != null ? expiration.getTime() : null);
                response.put("current_time", System.currentTimeMillis());
            }

            logger.info("Token验证结果: token={}, valid={}", token, isValid);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("Token验证异常: {} - {}", token, e.getMessage(), e);
            return ResponseEntity.internalServerError()
                    .body(ApiResponse.error(ResponseCode.SERVER_ERROR, "Token验证失败"));
        }
    }

    // 辅助方法：从请求头提取 Token
    private String extractToken(HttpServletRequest request) {
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }
        return null;
    }

    // 辅助方法：验证 Token 和用户 ID 是否匹配
    private ResponseEntity<?> validateTokenAndUserId(Integer userId, HttpServletRequest request) {
        String token = extractToken(request);
        if (token == null) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(ApiResponse.error(ResponseCode.UNAUTHORIZED, "未提供 Token"));
        }

        // 验证 Token 有效性
        if (!jwtUtil.validateToken(token)) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(ApiResponse.error(ResponseCode.UNAUTHORIZED, "Token 无效或已过期"));
        }

        // 从 Token 获取账号
        String tokenAccount = jwtUtil.getAccountFromToken(token);
        if (tokenAccount == null) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(ApiResponse.error(ResponseCode.UNAUTHORIZED, "无法解析 Token 信息"));
        }

        try {
            // 通过用户 ID 查询用户信息
            User user = userService.getUserById(userId);

            // 验证 Token 中的账号与用户账号是否匹配
            if (!user.getAccount().equals(tokenAccount)) {
                logger.warn("权限验证失败: 请求用户 {} 与 Token 账号 {} 不匹配", userId, tokenAccount);
                return ResponseEntity.status(HttpStatus.FORBIDDEN)
                        .body(ApiResponse.error(ResponseCode.FORBIDDEN, "无权访问该用户资源"));
            }
            return null; // 验证通过
        } catch (Exception e) {
            logger.error("用户验证失败: {} - {}", userId, e.getMessage());
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(ApiResponse.error(ResponseCode.NOT_FOUND, "用户不存在"));
        }
    }
}



